#include "NZ/NZConnection.h"
#include <QThread>

NZConnection::NZConnection()
{
   // m_tcpServer = new QTcpServer;
    m_tcpServerSocket = new QTcpSocket;
    m_udpClientSocket = new QUdpSocket;
    m_tcpServer = new QTcpServer;


    connect(m_tcpServer, &QTcpServer::newConnection, this, &NZConnection::slot_newTcpConnection);
    connect(&m_timerSendCmdList, &QTimer::timeout, this, &NZConnection::slot_sendTcpMsgList);

    connect(m_udpClientSocket, &QUdpSocket::readyRead, this, &NZConnection::slot_udpMsgRecv);

    m_indexSendCmdList = 0;
//    connect(m_tcpServerSocket, &QTcpSocket::readyRead, this, &NZConnection::slot_sendTcpMsgListNextOne);
}

NZConnection::~NZConnection()
{
    m_tcpServerSocket->abort();
    m_tcpServerSocket->close();
    m_udpClientSocket->abort();
    m_udpClientSocket->disconnect();
    m_tcpServerSocket->disconnect();
    m_tcpServer->close();
    m_tcpServerSocket->deleteLater();
    m_tcpServer->deleteLater();
}

void NZConnection::setIPsandPorts(QString tcpServerIP, QString udpServerIP, QString udpPort, QString tcpPort)
{
    m_tcpServerIP =  tcpServerIP;
    m_udpServerIP = udpServerIP;
    m_udpPort = udpPort;
    m_tcpPort = tcpPort;
}

void NZConnection::sendUdpMsg(const QString &msg)
{
    QHostAddress peerAddr(m_udpServerIP);
    QByteArray sendMsg = QByteArray::fromHex(msg.toLatin1());
    quint16 peerPort(m_udpPort.toUInt());  // 向1032 端口发送数据
//     m_udpClientSocket->bind(peerPort);
//     m_udpClientSocket->connectToHost(peerAddr, peerPort);

    qDebug() << "当前的UDP IP地址：" << peerAddr << "UDP端口号: "  << peerPort;
    m_udpClientSocket->writeDatagram(sendMsg, peerAddr, peerPort);    // 写udp报文数据 << "当前udp 客户端的状态: " << m_udpClientSocket->state();
    emit sig_sendUDPMsg("[UDP 发送] : " + msg);
}

void NZConnection::sendUdpMsg(const QByteArray &msg)
{
    QHostAddress peerAddr(m_udpServerIP);
    quint16 peerPort(m_udpPort.toUInt());  // 向1032 端口发送数据

    // qDebug() << "当前连接到的IP地址：" << peerAddr << "端口号: " << m_udpPort << peerPort;
    m_udpClientSocket->writeDatagram(msg, peerAddr, peerPort);    // 写udp报文数据 << "当前udp 客户端的
    emit sig_sendUDPMsg("[UDP 发送] : "+ msg);
}

bool NZConnection::tcpListen()
{
    // 监听所有保护设备的ip地址， ip 地址是保护设备上设置的，端口号主站本机的1048
    bool ret = m_tcpServer->listen(QHostAddress::Any, m_tcpPort.toUInt(nullptr,10));

    qDebug() << "tcp服务器开始listenning 端口 : " << m_tcpPort.toUInt(nullptr,10);

    QString errorMsg = m_tcpServer->errorString();
    if ( false == ret )
    {
        emit sig_sendTcpMsg("****tcp服务器开启监听错误！" + errorMsg + "*******");
    }
    emit sig_sendTcpMsg("******* tcp服务器开启成功。*********");

//    qDebug() <<" 初始化 tcp server 连接数。" << m_tcpServer->hasPendingConnections();
    //m_tcpServerSocket = m_tcpServer->nextPendingConnection();

    return  ret;
}

void NZConnection::stopTcpServer()
{
    m_tcpServerSocket->disconnectFromHost();
    m_tcpServer->close();
    m_udpClientSocket->disconnectFromHost();
}

void NZConnection::sendTcpMsg(const QString &msg)
{
    QByteArray bdata(QByteArray::fromHex(msg.toLatin1().toHex()));
    int len = m_tcpServerSocket->write(QByteArray::fromHex(bdata), bdata.length());
    QString lenStr =  QString::number(len);
    qDebug() << "发送消息" << msg << len;
    emit sig_sendTcpMsg("[tcp 发送 " + lenStr + " 字节消息]: " + msg);
}

void NZConnection::sendTcpMsg(const QByteArray &msg)
{
    qDebug() << "【发送tcp消息：】"<< msg;
    int writtenLen = m_tcpServerSocket->write(QByteArray::fromHex(msg), msg.length());

    if ( writtenLen == -1 )
    {
        emit sig_sendTcpMsg("发送错误！");
    }
    else {
        emit sig_sendTcpMsg("[tcp 发送 " + QString::number(writtenLen) + " 字节]: " +msg);
    }
}

void NZConnection::sendTcpMsg(const QStringList &msg)
{
    m_cmdListReadBill = msg;            // 初始化当前类成员
    m_timerSendCmdList.start(200);
}
void NZConnection::sendTcpMsg(const QByteArrayList &msg)
{
    m_cmdListReadAllBillInfo = msg;            // 初始化当前类成员
    qDebug() << "需要发送的报文有 ： " << msg;
    m_timerSendCmdList.start(ITIME_SENDCMD);
}

void NZConnection::slot_sendTcpMsgList()
{
    if ( m_indexSendCmdList == m_cmdListReadAllBillInfo.count())
    {
        m_timerSendCmdList.stop();
        m_indexSendCmdList = 0;
        return;
    }
    sendTcpMsg(m_cmdListReadAllBillInfo.at(m_indexSendCmdList));
    m_indexSendCmdList++;
}

void NZConnection::slot_sendTcpMsgListNextOne()
{
    // 确认是否是发送 CMDList 的任务
    if (!m_timerSendCmdList.isActive()) {
        return;
    }

    // 发送完毕否检查
    if ( m_indexSendCmdList == m_cmdListReadBill.count())
    {
        m_timerSendCmdList.stop();
        m_indexSendCmdList = 0;
        return;
    }

    // 逐个发送报文命令
    QThread::msleep(50);
    sendTcpMsg(m_cmdListReadAllBillInfo.at(m_indexSendCmdList));
    m_indexSendCmdList++;   // 待发送的报文序号移动下一个
}

QStringList NZConnection::getLocalHostIPList()
{
    QStringList strIpAddress;
    QList<QHostAddress> ipAddressesList = QNetworkInterface::allAddresses();
    int nListSize = ipAddressesList.size();

    for (int i = 0; i < nListSize; ++i)
    {
        if (ipAddressesList.at(i) != QHostAddress::LocalHost &&
                ipAddressesList.at(i).toIPv4Address()) {
            strIpAddress.append(ipAddressesList.at(i).toString());
        }
    }

    if (strIpAddress.isEmpty())
    {
        strIpAddress.append(QHostAddress(QHostAddress::LocalHost).toString());
    }

    return strIpAddress;
}


// 读取数据发给 103客户端
QString NZConnection::getDataFromTcpClient()
{
    if(m_tcpServerSocket == nullptr)
    {
        return "";
    }

    QByteArray buffer = m_tcpServerSocket->readAll();
    if (buffer.isEmpty())
    {
        return "";
    }

    emit sendTcpMsg("[接收到 "  +getConnectedInfo() + " 的消息] :" + buffer.toHex().toUpper());

    return buffer.toHex().toUpper();
}

QByteArray NZConnection::getDataFromTcp()
{
    if(m_tcpServerSocket == nullptr)
    {
        return "";
    }

    QByteArray buffer = m_tcpServerSocket->readAll();
    if (buffer.isEmpty())
    {
        return "";
    }

    emit sendTcpMsg("[接收到 "  +getConnectedInfo() + " 的消息] :" + buffer.toHex());

    return buffer.toHex();
}

// 新的tcp连接与服务端建立获取对应的ip port信息
QString NZConnection::getConnectedInfo()
{
    QString tcpIPStr = m_tcpServerSocket -> peerAddress().toString().split("::ffff:")[1];
    quint16 tcpPortStr = m_tcpServerSocket -> peerPort();
    qDebug() << "tcp 新接入连接ip" << tcpIPStr << " port : " << tcpPortStr;

    return tcpIPStr + " : " + QString::number(tcpPortStr,10);
}

bool NZConnection::isHasPendingDatagrams()
{
    return m_udpClientSocket->hasPendingDatagrams();
}

int NZConnection::pendingDatagramSize()
{
    return m_udpClientSocket->pendingDatagramSize();
}

void NZConnection::readDatagram(QByteArray datagram,QHostAddress &peerAddr,quint16 &peerPort)
{
    datagram.resize(m_udpClientSocket->pendingDatagramSize());

    m_udpClientSocket->readDatagram(datagram.data(), datagram.size(), &peerAddr, &peerPort);
}

void NZConnection::slot_readTcpRecv()
{
    QByteArray recvByte =  m_tcpServerSocket->readAll();
    qDebug() << "【接收tcp报文】 " << recvByte.toHex();
    emit sig_readyReadTcp(recvByte);
}

void NZConnection::slot_udpMsgRecv()
{
   while(m_udpClientSocket->hasPendingDatagrams())
   {
       QByteArray datagram;
       datagram.resize(m_udpClientSocket->pendingDatagramSize());
       QHostAddress peerAddr;
       quint16 peerPort;
       readDatagram(datagram.data(),peerAddr,peerPort);
//       QString headStr ="from [" +  peerAddr.toString() + ":" + QString::number(peerPort) +"] : ";
       emit sig_readyRadUdp(datagram, peerAddr.toString(),QString::number(peerPort));
   }
}

void NZConnection::slot_newTcpConnection()
{
    m_tcpServerSocket = m_tcpServer->nextPendingConnection();

    m_tcpSocketList.append(m_tcpServerSocket);

    // 当tcp socket 收到数据后，发出信号通知client
    connect(m_tcpServerSocket, &QTcpSocket::readyRead, this, &NZConnection::slot_readTcpRecv);

    QString tcpIPStr = m_tcpServerSocket -> peerAddress().toString().split("::ffff:")[1];
    quint16 tcpPortStr = m_tcpServerSocket -> peerPort();

    emit sig_newTcpConnection( "新连接进入" + tcpIPStr + " : " +  QString::number(tcpPortStr,10) );
}
